﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

using Compiler;

namespace UnifyAlgoApplication
{
    public partial class FormMain : Form
    {
        private static string SUCCESS_COMPILE = "Компиляция прошла успешно";
        private static string FAIL_COMPILE = "Обнаружены ошибки:" + Environment.NewLine;
        private static string EXCEPTION_COMPILE = "Произошла непредвиденная ошибка!" + Environment.NewLine;

        private const string CS_FILES_FILTER = "C#-ext files|*.cs";
        private const string DLL_FILES_FILTER = "DLL files|*.dll";

        private ConceptsCompiler compiler = new ConceptsCompiler();

        private string openedFileName;
        private bool newFileOpening = false;

        public FormMain()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            сохранитьToolStripMenuItem.Enabled = false;
            openedFileName = "";
        }

        private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialogMain.Filter = CS_FILES_FILTER;
            if (openFileDialogMain.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (!File.Exists(openFileDialogMain.FileName))
                {
                    MessageBox.Show("Файл не существует!");
                    return;
                }
                try
                {
                    StreamReader sr = new StreamReader(openFileDialogMain.FileName);
                    string programCode = sr.ReadToEnd();
                    sr.Close();
                    openedFileName = openFileDialogMain.FileName;
                    сохранитьToolStripMenuItem.Enabled = true;
                    textBoxFileName.Text = openedFileName;
                    newFileOpening = true;
                    textBoxCode.Text = programCode;
                }
                catch (Exception exc)
                { MessageBox.Show(exc.ToString()); }
            }
        }

        private void компилироватьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var result = compiler.Compile(textBoxCode.Text);
            textBoxResult.Text = "";
            if (result.Success)
                textBoxResult.Text = SUCCESS_COMPILE + Environment.NewLine + Environment.NewLine;
            else
            {
                if (result.ExceptionError != "")
                    textBoxResult.Text += EXCEPTION_COMPILE + Environment.NewLine
                        + result.ExceptionError + Environment.NewLine;
                if (result.HasErrors)
                {
                    textBoxResult.Text += FAIL_COMPILE + Environment.NewLine;
                    foreach (string error in result.Errors)
                        textBoxResult.Text += error + Environment.NewLine;
                }
                textBoxResult.Text += Environment.NewLine;
            }
            if (result.Warnings.Count > 0)
                foreach (string warning in result.Warnings)
                    textBoxResult.Text += warning + Environment.NewLine;
            if (result.DebugMessages.Count > 0)
                foreach (string message in result.DebugMessages)
                    textBoxResult.Text += message + Environment.NewLine;
        }

        private void textBoxCode_TextChanged(object sender, EventArgs e)
        {
            if (newFileOpening)
                newFileOpening = false;
            else
                textBoxFileName.Text = "* " + openedFileName;
        }

        private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _TrySave(openedFileName);
        }

        private void сохранитьКакToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileDialogMain.Filter = CS_FILES_FILTER;
            if (saveFileDialogMain.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                _TrySave(saveFileDialogMain.FileName);
        }

        private bool _TrySave(string fileName)
        {
            try
            {
                StreamWriter sw = new StreamWriter(fileName);
                sw.Write(textBoxCode.Text);
                sw.Close();
                textBoxFileName.Text = fileName;
                openedFileName = fileName;
                сохранитьToolStripMenuItem.Enabled = true;
                return true;
            }
            catch (Exception exc)
            { 
                MessageBox.Show(exc.ToString());
                return false;
            }
        }

        private void подключитьБиблиотекуToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialogMain.Filter = DLL_FILES_FILTER;
            if (openFileDialogMain.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (!File.Exists(openFileDialogMain.FileName))
                {
                    MessageBox.Show("Файл не существует!");
                    return;
                }
                if (compiler.ContainsDLL(openFileDialogMain.FileName))
                    return;
                compiler.AddDLL(openFileDialogMain.FileName);
                checkedListBoxLibs.Items.Add(openFileDialogMain.FileName);
            }
        }

        private void buttonRemoveLib_Click(object sender, EventArgs e)
        {
            LinkedList<object> removedDlls = new LinkedList<object>();
            foreach (object dll in checkedListBoxLibs.SelectedItems)
            {
                compiler.RemoveDLL(dll.ToString());
                removedDlls.AddLast(dll);
            }
            foreach (object dll in removedDlls)
                checkedListBoxLibs.Items.Remove(dll);
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (textBoxFileName.Text.StartsWith("*"))
                if (MessageBox.Show("Файл не сохранён. Всё равно закрыть форму?", "Завершение работы", MessageBoxButtons.YesNo)
                    == System.Windows.Forms.DialogResult.No)
                    e.Cancel = true;
        }

        private void шрифтРедактораToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (fontDialogMain.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                textBoxCode.Font = fontDialogMain.Font;
        }

        private void шрифтОкнаРезультатаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (fontDialogMain.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                textBoxResult.Font = fontDialogMain.Font;
        }
    }
}
